package com.franklin.ideaplugin.maphelper.resolver.impl.map;

import cn.hutool.core.collection.CollectionUtil;
import com.franklin.ideaplugin.api.beans.declaration.IDeclaration;
import com.franklin.ideaplugin.api.utils.psi.PsiClassUtils;
import com.franklin.ideaplugin.maphelper.beans.colmember.IColMember;
import com.franklin.ideaplugin.maphelper.col.declaration.IColDeclaration;
import com.franklin.ideaplugin.maphelper.resolver.impl.collection.CollectionMemberResolverFactory;
import com.google.common.collect.Sets;
import com.intellij.psi.*;

import java.util.Collection;
import java.util.Objects;
import java.util.Set;

/**
 * 解析Collection<Map>的成员
 *
 * @author Ye Junhui
 * @since 2024/3/8
 */
public class CollectionMapMemberResolver implements IMapMemberResolver {

    public final static CollectionMapMemberResolver INSTANCE = new CollectionMapMemberResolver();

    @Override
    public boolean supports(IColDeclaration colDeclaration) {
        IDeclaration declaration = colDeclaration.getDeclaration();
        //校验类型
        PsiType psiType = declaration.getPsiType();
        if (Objects.isNull(psiType)){
            return false;
        }
        if (!PsiClassType.class.isInstance(psiType)) {
            return false;
        }
        PsiClassType psiClassType = (PsiClassType) psiType;
        PsiClass psiClass = psiClassType.resolve();
        if (!PsiClassUtils.isJavaCollectionClass(psiClass)) {
            return false;
        }

        //泛型
        if (psiClassType.getParameterCount() != 1) {
            return false;
        }
        PsiType genericType = psiClassType.getParameters()[0];
        if (!PsiClassType.class.isInstance(genericType)) {
            return false;
        }
        PsiClassType genericClassType = (PsiClassType) genericType;
        PsiClass genericClass = genericClassType.resolve();
        if (!PsiClassUtils.isJavaMapClass(genericClass)) {
            return false;
        }
        return true;
    }

    @Override
    public Collection<IColMember> resolveColMembers(PsiElement psiExpression, IColDeclaration colDeclaration) {
        //结果
        Set<IColMember> result = Sets.newLinkedHashSet();

        //寻找真表达式
        PsiElement psiElement = colDeclaration.getDeclaration().getPsiElement();

        //寻找集合成员
        Collection<IColMember> collectionMembers = CollectionMemberResolverFactory.getInstance()
                .resolveExpression(psiElement, colDeclaration);

        //map成员解析工厂
        MapMemberResolverFactory colMemberResolverFactory = getColMemberResolverFactory();

        //解析成员
        collectionMembers.forEach(collectionMember -> {
            //成员
            Collection<IColMember> colMembers = collectionMember.getChildren(colMemberResolverFactory);
            CollectionUtil.addAll(result,colMembers);
        });

        return result;
    }
}
